﻿using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Media;

namespace CPlatePrintSys.Annotation.Converters
{
    /// <summary>
    /// This class is responsible for converting line dash styles from the DXF format to the corresponding WPF format.
    /// </summary>
    internal static class LinDashStyleConverter
    {
        // Define readonly string constants for keywords
        private static readonly string KeywordSolid = "SOLID";
        private static readonly string KeywordDash = "DASH";
        private static readonly string KeywordDotted = "DOTTED";
        private static readonly string KeywordDashDot = "DASHDOT";

        private static readonly Dictionary<string, DashStyle> DashStyleMappings = new Dictionary<string, DashStyle>(StringComparer.OrdinalIgnoreCase);

        static LinDashStyleConverter()
        {
            LoadMappingsFromConfig();
        }

        /// <summary>
        /// Loads the mappings between DXF line types and WPF DashStyles from the linConfig.txt file.
        /// </summary>
        private static void LoadMappingsFromConfig()
        {
            string configFilePath = Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "linConfig.txt");

            if (!File.Exists(configFilePath))
            {
                throw new FileNotFoundException($"Configuration file not found: {configFilePath}");
            }

            foreach (var line in File.ReadLines(configFilePath))
            {
                // Skip empty lines or comments
                if (string.IsNullOrWhiteSpace(line) || line.StartsWith("//"))
                {
                    continue;
                }

                // Split the line into DXF line type and DashStyle (tab-separated)
                var parts = line.Split('\t');
                if (parts.Length != 2)
                {
                    continue; // Skip invalid lines
                }

                string dxfLineType = parts[0].Trim();
                string dashStyleDefinition = parts[1].Trim();

                // Parse the DashStyle
                DashStyle dashStyle = ParseDashStyle(dashStyleDefinition);
                if (dashStyle != null)
                {
                    DashStyleMappings[dxfLineType] = dashStyle;
                }
            }
        }

        /// <summary>
        /// Parses a DashStyle definition string into a DashStyle object.
        /// </summary>
        /// <param name="definition">The DashStyle definition string (e.g., "DashDot(2,2,0,2)").</param>
        /// <returns>The corresponding DashStyle object, or null if parsing fails.</returns>
        private static DashStyle ParseDashStyle(string definition)
        {
            if (definition.Equals(KeywordSolid, StringComparison.OrdinalIgnoreCase))
            {
                return DashStyles.Solid;
            }
            else if (definition.StartsWith("DashDot", StringComparison.OrdinalIgnoreCase))
            {
                var values = ExtractDashArray(definition);
                return new DashStyle(values, 0);
            }
            else if (definition.StartsWith("Dash", StringComparison.OrdinalIgnoreCase))
            {
                var values = ExtractDashArray(definition);
                return new DashStyle(values, 0);
            }
            else if (definition.StartsWith("Dot", StringComparison.OrdinalIgnoreCase))
            {
                var values = ExtractDashArray(definition);
                return new DashStyle(values, 0);
            }

            return DashStyles.Solid;
        }

        /// <summary>
        /// Extracts a double array from a DashStyle definition string.
        /// </summary>
        /// <param name="definition">The DashStyle definition string (e.g., "DashDot(2,2,0,2)").</param>
        /// <returns>An array of doubles representing the dash pattern.</returns>
        private static double[] ExtractDashArray(string definition)
        {
            int start = definition.IndexOf('(');
            int end = definition.IndexOf(')');
            if (start >= 0 && end > start)
            {
                string content = definition.Substring(start + 1, end - start - 1);
                return content.Split(',').Select(double.Parse).ToArray();
            }

            return Array.Empty<double>();
        }

        /// <summary>
        /// Gets the corresponding DashStyle for a given DXF line type.
        /// </summary>
        /// <param name="lineType">The DXF line type name.</param>
        /// <returns>The corresponding DashStyle, or DashStyles.Solid if no match is found.</returns>
        public static DashStyle GetDashStyle(string lineType)
        {
            if (DashStyleMappings.TryGetValue(lineType, out var dashStyle))
            {
                return dashStyle;
            }

            if (lineType.IndexOf(KeywordSolid, StringComparison.OrdinalIgnoreCase) >= 0)
            {
                return DashStyles.Solid;
            }
            else if (lineType.IndexOf(KeywordDashDot, StringComparison.OrdinalIgnoreCase) >= 0)
            {
                return DashStyles.DashDot;
            }
            else if (lineType.IndexOf(KeywordDash, StringComparison.OrdinalIgnoreCase) >= 0)
            {
                return DashStyles.Dash;
            }
            else if (lineType.IndexOf(KeywordDotted, StringComparison.OrdinalIgnoreCase) >= 0)
            {
                return DashStyles.Dot;
            }


            return DashStyles.Solid; // Default to solid
        }
    }
}
